assert(TrackCooldowns, "TrackCooldowns not found!")

local pairs = _G.pairs
local GetTime = _G.GetTime
local GetSpellCooldown = _G.GetSpellCooldown
local L = LibStub("AceLocale-3.0"):GetLocale("TrackCooldowns")

local transmit = {}

function transmit:OnInitialize()
	self:SetEnabledState(false)
end

function transmit:OnEnable()
	self.canScanCooldowns = true
	self:ScanSpells()
	self:RegisterEvent("CHARACTER_POINTS_CHANGED", "ChangingSpecialization")
	self:RegisterEvent("CONFIRM_TALENT_WIPE", "ChangingSpecialization")
	self:RegisterEvent("PLAYER_TALENT_UPDATE", "ChangingSpecialization")
	self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", "GenericSpellSuccess")
	self:RegisterEvent("SPELL_UPDATE_COOLDOWN", "ScanSpells")
end

function transmit:OnDisable()
	self:UnregisterAllEvents()
	
	if DXE then
		DXE.UnregisterCallback(TrackCooldowns, "TriggerDefeat")
	end
end

function transmit:QuickCheck(t)
	local qc = getmetatable(self)["__index"]
	return qc[t](qc == transmit and self or qc)
end

--------------[[		Combat Events		]]--------------

function transmit:GenericSpellSuccess(event, unit, spell)
	if not self.enabled then return end
	if unit ~= "player" then return end
	if self.cooldowns[spell] == nil then return end
	self.canScanCooldowns = true
end

function transmit:ChangingSpecialization(event)
	if not self.enabled then return end
	self.canScanCooldowns = true
	self:ScanSpells()
end

function transmit:GetCooldown(spell)
	if not self.enabled then return end
	local remaining = 0
	local startTime, cooldown, enabled = GetSpellCooldown(spell)

	if startTime and startTime > 0 and cooldown >= 2 and enabled == 1 then
		remaining = math.ceil(startTime + cooldown - GetTime())
	end

	return remaining
end

--------------[[		Comm Methods		]]--------------

function transmit:Sync(data, cooldown)
	if not self.enabled then return end
	if UnitInParty("player") then return end

	local channel
	if UnitInRaid("player") then
		channel = "RAID"
	elseif UnitInBattleground("player") then
		channel = "BATTLEGROUND"
	else
		channel = false
	end
	if not channel then return end

	if cooldown == nil then return end
	local id = data

	if type(data) == "table" then
		id = data.id

		if not oRA and data.ora ~= nil then
			TrackCooldowns:SendCommMessage("oRA", "CD " .. data.ora .. " " .. (cooldown / 60), channel)
		end

	end
	
	TrackCooldowns:SendCommMessage(TrackCooldowns.prefix, (id .. " " .. cooldown), channel)
end

function transmit:versionCheck(data)
	local ver = data

	if type(data) == "table" then
		ver = data.ver
		TrackCooldowns:SendCommMessage(TrackCooldowns.prefix, ver, "RAID")
	end

end

function transmit:ScanSpells()
	if not self.enabled then return end
	if self.canScanCooldowns == false then return end
	local cooldown

	for k, v in pairs(self.cooldowns) do
		cooldown = self:GetCooldown(k)

		if cooldown == 0 or cooldown > 2 then
			self:Sync(v, cooldown)
		end

	end

	self.canScanCooldowns = false
end

TrackCooldowns.ModuleBase = transmit